package cn.iocoder.yudao.module.vote.service.fielddynamicsconfig;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.vote.constants.RedisConst;
import cn.iocoder.yudao.module.vote.controller.admin.fielddynamicsconfig.vo.FieldDynamicsConfigCreateReqVO;
import cn.iocoder.yudao.module.vote.controller.admin.fielddynamicsconfig.vo.FieldDynamicsConfigExportReqVO;
import cn.iocoder.yudao.module.vote.controller.admin.fielddynamicsconfig.vo.FieldDynamicsConfigPageReqVO;
import cn.iocoder.yudao.module.vote.controller.admin.fielddynamicsconfig.vo.FieldDynamicsConfigUpdateReqVO;
import cn.iocoder.yudao.module.vote.convert.fielddynamicsconfig.FieldDynamicsConfigConvert;
import cn.iocoder.yudao.module.vote.dal.dataobject.fielddynamicsconfig.FieldDynamicsConfigDO;
import cn.iocoder.yudao.module.vote.dal.mysql.fielddynamicsconfig.FieldDynamicsConfigMapper;
import cn.iocoder.yudao.module.vote.utils.RedisService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.vote.enums.ErrorCodeConstants.FIELD_DYNAMICS_CONFIG_NOT_EXISTS;

/**
 * 表动态配置字段展示 Service 实现类
 *
 * @author moving
 */
@Service
@Validated
public class FieldDynamicsConfigServiceImpl implements FieldDynamicsConfigService {

    @Resource
    private FieldDynamicsConfigMapper fieldDynamicsConfigMapper;

    @Resource
    private RedisService redisService;

    @Override
    public Long createFieldDynamicsConfig(FieldDynamicsConfigCreateReqVO createReqVO) {
        // 插入
        FieldDynamicsConfigDO fieldDynamicsConfig = FieldDynamicsConfigConvert.INSTANCE.convert(createReqVO);
        fieldDynamicsConfigMapper.insert(fieldDynamicsConfig);
        // 返回
        return fieldDynamicsConfig.getId();
    }

    @Override
    public void updateFieldDynamicsConfig(FieldDynamicsConfigUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateFieldDynamicsConfigExists(updateReqVO.getId());
        // 更新
        FieldDynamicsConfigDO updateObj = FieldDynamicsConfigConvert.INSTANCE.convert(updateReqVO);
        updateObj.setOrderList(JSONObject.toJSONString(updateReqVO.getOrderFrontList()));
        fieldDynamicsConfigMapper.updateById(updateObj);

        redisService.set(redisFieldKey(updateReqVO.getTableName()),updateReqVO);

    }

    private String redisFieldKey(String tableName){
        return StrUtil.format(RedisConst.FIELD_CONFIG_INFO,tableName);
    }

    @Override
    public void deleteFieldDynamicsConfig(Long id) {
        // 校验存在
        this.validateFieldDynamicsConfigExists(id);
        // 删除
        fieldDynamicsConfigMapper.deleteById(id);
    }

    private void validateFieldDynamicsConfigExists(Long id) {
        if (fieldDynamicsConfigMapper.selectById(id) == null) {
            throw exception(FIELD_DYNAMICS_CONFIG_NOT_EXISTS);
        }
    }

    @Override
    public FieldDynamicsConfigDO getFieldDynamicsConfig(Long id) {
        return fieldDynamicsConfigMapper.selectById(id);
    }

    @Override
    public List<FieldDynamicsConfigDO> getFieldDynamicsConfigList(Collection<Long> ids) {
        return fieldDynamicsConfigMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<FieldDynamicsConfigDO> getFieldDynamicsConfigPage(FieldDynamicsConfigPageReqVO pageReqVO) {
        return fieldDynamicsConfigMapper.selectPage(pageReqVO);
    }

    @Override
    public List<FieldDynamicsConfigDO> getFieldDynamicsConfigList(FieldDynamicsConfigExportReqVO exportReqVO) {
        return fieldDynamicsConfigMapper.selectList(exportReqVO);
    }

    @Override
    public FieldDynamicsConfigDO getByTableName(Class className){

        TableInfo tableInfo = TableInfoHelper.getTableInfo(className);
        if(redisService.hasKey(tableInfo.getTableName())){
            return redisService.getCacheObject(tableInfo.getTableName());
        }

        FieldDynamicsConfigDO fieldConfig = fieldDynamicsConfigMapper.getByTableName(tableInfo.getTableName());
        return fieldConfig;
    }



    @Override
    public Predicate getDynamicFields(FieldDynamicsConfigDO fieldConfig){


        List<Predicate<TableFieldInfo>> predicateList = new ArrayList<>();
        if(fieldConfig==null){
            return predicateList.stream().reduce(x->true,Predicate::or);
        }
        /**
         * 需要显示的字段
         */
        for (String field : fieldConfig.getShowFieldList().split(",")) {
            Predicate<TableFieldInfo> predicate = i -> i.getColumn().equalsIgnoreCase(field);
            predicateList.add(predicate);
        }
        /**
         * 必须查询的字段
         */
        for (String field : fieldConfig.getMustFieldList().split(",")) {
            Predicate<TableFieldInfo> predicate = i -> i.getColumn().equalsIgnoreCase(field);
            predicateList.add(predicate);
        }
        return predicateList.stream().reduce(i->false,Predicate::or);
    }


}
